package com.ndp.fb.walle.business.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ndp.ec.core.FeedService;
import com.ndp.ec.core.ProductSetService;
import com.ndp.fb.enums.PlatForm;
import com.ndp.fb.rdb.api.AudienceManagerRdbService;
import com.ndp.fb.rdb.api.FeedRdbService;
import com.ndp.fb.rdb.api.ProductManageRdbService;
import com.ndp.fb.rdb.model.EntrustAccount;
import com.ndp.fb.rdb.model.FeedWe;
import com.ndp.fb.rdb.model.productmanage.ProductManage;
import com.ndp.fb.walle.business.AdPublishConditionService;
import com.ndp.fb.walle.business.EcService;
import com.ndp.fb.walle.business.EntrustAccountService;
import com.ndp.fb.walle.model.bo.useraudience.result.ProductExt;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ndp.fb.constant.CommonConstants;
import com.ndp.fb.enums.ErrorType;
import com.ndp.fb.enums.TargetingType;
import com.ndp.fb.enums.publish.OptimizationGoal;
import com.ndp.fb.enums.publish.PublishStatus;
import com.ndp.fb.enums.targetingspec.Connections;
import com.ndp.fb.enums.targetingspec.Gender;
import com.ndp.fb.enums.targetingspec.InterestedInType;
import com.ndp.fb.enums.targetingspec.LocationType;
import com.ndp.fb.enums.targetingspec.PageType;
import com.ndp.fb.enums.targetingspec.RelationShipStatusType;
import com.ndp.fb.enums.targetingspec.UserOs;
import com.ndp.fb.enums.targetingspec.WirelessCarrier;
import com.ndp.fb.exception.BusinessException;
import com.ndp.fb.fbagent.service.TargetingSpecFBService;
import com.ndp.fb.model.business.bo.targetingspec.Age;
import com.ndp.fb.model.business.bo.targetingspec.Behavior;
import com.ndp.fb.model.business.bo.targetingspec.BroadCategory;
import com.ndp.fb.model.business.bo.targetingspec.City;
import com.ndp.fb.model.business.bo.targetingspec.CollegeYear;
import com.ndp.fb.model.business.bo.targetingspec.Country;
import com.ndp.fb.model.business.bo.targetingspec.CustomAudience;
import com.ndp.fb.model.business.bo.targetingspec.EducationMajor;
import com.ndp.fb.model.business.bo.targetingspec.EducationSchool;
import com.ndp.fb.model.business.bo.targetingspec.EducationStatus;
import com.ndp.fb.model.business.bo.targetingspec.EthnicAffinity;
import com.ndp.fb.model.business.bo.targetingspec.FacebookConnection;
import com.ndp.fb.model.business.bo.targetingspec.FamilyStatus;
import com.ndp.fb.model.business.bo.targetingspec.FbLocation;
import com.ndp.fb.model.business.bo.targetingspec.Generation;
import com.ndp.fb.model.business.bo.targetingspec.Industry;
import com.ndp.fb.model.business.bo.targetingspec.Interest;
import com.ndp.fb.model.business.bo.targetingspec.InterestedIn;
import com.ndp.fb.model.business.bo.targetingspec.Language;
import com.ndp.fb.model.business.bo.targetingspec.LifeEvent;
import com.ndp.fb.model.business.bo.targetingspec.LocalConnection;
import com.ndp.fb.model.business.bo.targetingspec.LocalCustomAudience;
import com.ndp.fb.model.business.bo.targetingspec.LocalGender;
import com.ndp.fb.model.business.bo.targetingspec.LocalInterest;
import com.ndp.fb.model.business.bo.targetingspec.LocalLocation;
import com.ndp.fb.model.business.bo.targetingspec.LocalPageType;
import com.ndp.fb.model.business.bo.targetingspec.Location;
import com.ndp.fb.model.business.bo.targetingspec.Platform;
import com.ndp.fb.model.business.bo.targetingspec.Politic;
import com.ndp.fb.model.business.bo.targetingspec.RelationshipStatus;
import com.ndp.fb.model.business.bo.targetingspec.TargetingDescriptionBo;
import com.ndp.fb.model.business.bo.targetingspec.WorkEmployer;
import com.ndp.fb.model.business.bo.targetingspec.WorkPosition;
import com.ndp.fb.model.business.bo.useraudience.result.FBTargetingSpecs;
import com.ndp.fb.model.business.bo.useraudience.result.LocalTargetingSpecs;
import com.ndp.fb.model.business.bo.useraudience.result.TargetingSpecBo;
import com.ndp.fb.model.business.bo.useraudience.result.TargetingSpecGroupBo;
import com.ndp.fb.model.business.vo.cache.result.EntrustAccountVo;
import com.ndp.fb.model.business.vo.cache.result.FbUserVo;
import com.ndp.fb.model.business.vo.cache.result.PublishCache;
import com.ndp.fb.model.business.vo.cache.result.UserAudienceCache;
import com.ndp.fb.model.fbagent.param.APIPriority;
import com.ndp.fb.model.fbagent.param.ApiCallBackTarget;
import com.ndp.fb.model.fbagent.param.useraudience.TargetingSpecParam;
import com.ndp.fb.model.fbagent.result.common.FbTargetingSentencelines;
import com.ndp.fb.rdb.api.FbUserRdbService;
import com.ndp.fb.rdb.model.FbUser;
import com.ndp.fb.redis.api.RedisClient;
import com.ndp.fb.util.ListUtil;
import com.ndp.fb.walle.business.CacheService;
import com.ndp.fb.walle.business.UserAudienceService;
import com.ndp.fb.walle.model.bo.useraudience.result.PreviewUserAudienceResult;
import com.ndp.fb.walle.model.vo.entrustaccount.param.EntrustAccountParam;
import com.ndp.fb.walle.model.vo.useraudience.param.UserAudienceParam;
import com.ndp.fb.walle.util.BuildCacheUtils;
import com.ndp.fb.walle.util.ResponseUtils;

/**
 * Created by Jacky on 2015/1/29.
 */
@Component
public class UserAudienceServiceImpl implements UserAudienceService {
    private final org.slf4j.Logger LOG = LoggerFactory.getLogger(getClass());

    @Autowired
    private CacheService cacheService;

    @Reference
    private TargetingSpecFBService targetingHelper;
    @Reference
    private FbUserRdbService fbUserRdbService;
    
    @Autowired
    RedisClient redisClient;

    @Autowired
    private AdPublishConditionService adPublishConditionService;

    @Reference
    private FeedRdbService feedRdbService;

    @Reference
    private ProductManageRdbService productManageRdbService;

    @Autowired
    private EntrustAccountService entrustAccountService;

    @Reference
    private ProductSetService productsetService;

    @Reference
    private FeedService feedService;

    @Autowired
    private EcService ecService;

    @Override
    public Integer previewUserAudiences(UserAudienceParam userAudienceParam, FbUser fbUser) throws BusinessException {
        String cacheId = userAudienceParam.getCacheId();
        PublishCache cache = cacheService.fetch(cacheId);

        if (null == cache) {
            LOG.error("UserAudienceServiceImpl->previewUserAudiences->缓存Id：" + cacheId + "，失效！");
            throw new BusinessException(ErrorType.AD_CACHE_FAILURE);
        }

        // 前端传来的Json转为targetingSpecGroup
        List<TargetingSpecGroupBo> groups = getTargetingSpecGroups(userAudienceParam.getTargetingSpecGroups());

        // 解析用户定位组
        Map<String, TargetingSpecGroupBo> map = parseTargetingSpecGroups(groups);

        //设置用户定位缓存
        String userAudienceCacheId = UUID.randomUUID().toString();
        UserAudienceCache userAudienceCache = new UserAudienceCache();
        userAudienceCache.setTargetingSpecGroups(userAudienceParam.getTargetingSpecGroups());
        userAudienceCache.setPreviewTargetingSpecGroups(map);
        userAudienceCache.setIsComplete(false);
        userAudienceCache.setGroupCount(groups.size());
        userAudienceCache.setUserAudienceCacheId(userAudienceCacheId);
        cache.setUserAudience(userAudienceCache);
        //modify by sisi 生成新的用户定位则清空出价缓存
        cache.setSchedule(null);
        cache.setBidCache(null);
        cacheService.update(cacheId, cache);

        //构造预览用户定位请求
        try {
            //取一次最新的 accesstoken
            fbUser = fbUserRdbService.getFbUserByUserId(fbUser.getUserId());
            FbUserVo fbUserVo = BuildCacheUtils.getFbUserVo(fbUser);
            cache.setFbUserVo(fbUserVo);
            previewUserAudience(cacheId, userAudienceCacheId, fbUserVo, cache.getEntrustAccounts(), groups);
        } catch (Exception e) {
            ErrorType errorType = ErrorType.INTERNAL_EXCEPTION;
            LOG.error("UserAudienceServiceImpl->previewUserAudiences：" + e.getMessage(), e);
            throw new BusinessException(errorType);
        }

        return userAudienceCache.getGroupCount();
    }


    @Override
    public PreviewUserAudienceResult searchPreviewUserAudienceResult(String cacheId) throws BusinessException {
        //1、查询批次缓存
        PublishCache cache = cacheService.fetch(cacheId);
        if (null == cache) {
            LOG.info("UserAudienceServiceImpl->searchPreviewUserAudienceResult->缓存Id：" + cacheId + "，失效！");
            throw new BusinessException(ErrorType.AD_CACHE_FAILURE);
        }

        //2、获取PublishCache下的UserAudienceCache
        UserAudienceCache userAudienceCache = cache.getUserAudience();
        if (null == userAudienceCache || CollectionUtils.isEmpty(userAudienceCache.getPreviewTargetingSpecGroups())) {
            LOG.info("UserAudienceServiceImpl->searchPreviewUserAudienceResult->缓存Id："
                    + cacheId + "，下UserAudienceCache不存在或UserAudienceCache无待预览用户定位组！");
            throw new BusinessException(ErrorType.AD_CACHE_FAILURE);
        }
//        3、获取UserAudienceCache已经获取FB响应的用户定位组，返给前端
        List<TargetingSpecGroupBo> targetingSpecGroupBoes = new ArrayList<TargetingSpecGroupBo>();

        boolean isComplete = userAudienceCache.getIsComplete();
        if (isComplete) {
            Map<String, TargetingSpecGroupBo> previewTargetingSpecGroups = userAudienceCache.getPreviewTargetingSpecGroups();
            for (Map.Entry<String, TargetingSpecGroupBo> entry : previewTargetingSpecGroups.entrySet()) {
                targetingSpecGroupBoes.add(entry.getValue());
            }
        } else {
            Map<String, TargetingSpecGroupBo> previewTargetingSpecGroups = userAudienceCache.getPreviewTargetingSpecGroups();
            String userAudienceCacheId = userAudienceCache.getUserAudienceCacheId();
            for (Map.Entry<String, TargetingSpecGroupBo> entry : previewTargetingSpecGroups.entrySet()) {
                TargetingSpecGroupBo targetingSpecGroupBo = entry.getValue();
                String groupId = targetingSpecGroupBo.getGroupId();
                String userAudienceCacheKey = buildPreviewUserAudienceGroupKey(cacheId, userAudienceCacheId, groupId);
                TargetingSpecGroupBo cacheGroupBo = (TargetingSpecGroupBo) cacheService.fetchObject(userAudienceCacheKey);
                if (cacheGroupBo != null) {
                    targetingSpecGroupBoes.add(cacheGroupBo);
                }
            }
        }

        //4、构造PreviewUserAudienceResult
        PreviewUserAudienceResult previewUserAudienceResult = new PreviewUserAudienceResult();
        previewUserAudienceResult.setGroupCount(userAudienceCache.getGroupCount());
        previewUserAudienceResult.setPreviewUserAudienceResults(targetingSpecGroupBoes);
        previewUserAudienceResult.setIsComplete(isComplete);

        return previewUserAudienceResult;
    }

    private String buildPreviewUserAudienceGroupKey(String publishCacheId, String userAudienceCacheId, String groupId) {

        return "previewUserAudience" +
                CommonConstants.SYMBOL_UNDERLINE + publishCacheId +
                CommonConstants.SYMBOL_UNDERLINE + userAudienceCacheId +
                CommonConstants.SYMBOL_UNDERLINE + groupId;
    }


    private void previewUserAudience(String batchCacheId, String userAudienceCacheId,
                                     FbUserVo userFbVo,
                                     List<EntrustAccountVo> entrustAccounts, List<TargetingSpecGroupBo> groups) {
        //将用户定位组平均分发到账号中
        Map<Long, List<TargetingSpecGroupBo>> accountTargetingSpecGroups = buildAccountGroups(entrustAccounts, groups);

        //根据账号发送用户定位请求
        previewUserAudienceByAccounts(batchCacheId, userAudienceCacheId, accountTargetingSpecGroups, userFbVo.getAccessToken());
    }

    private Map<Long, List<TargetingSpecGroupBo>> buildAccountGroups(List<EntrustAccountVo> entrustAccounts, List<TargetingSpecGroupBo> groups) {
        //对于支持自定义受众的组，按指定账号分发
        Map<Long, List<TargetingSpecGroupBo>> accountTargetingSpecGroups = new HashMap<>();
        List<TargetingSpecGroupBo> noAccountGroups = new ArrayList<>();
        Long fbAccountId;
        for (TargetingSpecGroupBo targetingSpecGroupBo : groups) {
            fbAccountId = targetingSpecGroupBo.getFbAccountId();
            if (null == fbAccountId) {
                noAccountGroups.add(targetingSpecGroupBo);
            } else {
                List<TargetingSpecGroupBo> tempGroups = accountTargetingSpecGroups.get(fbAccountId);
                if (null == tempGroups) {
                    tempGroups = new ArrayList<>();
                    accountTargetingSpecGroups.put(fbAccountId, tempGroups);
                }
                tempGroups.add(targetingSpecGroupBo);
            }
        }

        //对于不区分账号的组，平均分发到不涉及自定义受众的其他账号中，避免涉及自定义受众的账号请求用户定位过多
        List<Long> accounts = new ArrayList();
        for (EntrustAccountVo entrustAccountVo : entrustAccounts) {
            accounts.add(entrustAccountVo.getFbAccountId());
        }

        Map<Long, List<TargetingSpecGroupBo>> noAccountTargetingSpecGroups
                = distributeGroupToAccount(accounts, noAccountGroups);
        if (!CollectionUtils.isEmpty(noAccountTargetingSpecGroups)) {
            Long accountId;
            for (Map.Entry<Long, List<TargetingSpecGroupBo>> temp : noAccountTargetingSpecGroups.entrySet()){
                accountId = temp.getKey();
                if (null == accountTargetingSpecGroups.get(accountId)){
                    accountTargetingSpecGroups.put(accountId, temp.getValue());
                } else {
                    accountTargetingSpecGroups.get(accountId).addAll(temp.getValue());
                }
            }
        }
        return accountTargetingSpecGroups;
    }


    private Map<Long, List<TargetingSpecGroupBo>> distributeGroupToAccount(
            List<Long> entrustAccounts, List<TargetingSpecGroupBo> noAccountGroups) {
        if (CollectionUtils.isEmpty(entrustAccounts) || CollectionUtils.isEmpty(noAccountGroups)) {
            return null;
        }

        Map<Long, List<TargetingSpecGroupBo>> noAccountTargetingSpecGroups = new HashMap<>();
        int size = noAccountGroups.size() / entrustAccounts.size();
        int left = noAccountGroups.size() % entrustAccounts.size();
        int i = 0;
        //将用户定位组平均分发到账号中
        if (0 < size) {
            for (; i < entrustAccounts.size(); i++) {
                noAccountTargetingSpecGroups.put(entrustAccounts.get(i), new ArrayList<>(noAccountGroups.subList(i * size, (i + 1) * size)));
            }
        }

        //处理剩余的组
        if (0 < left) {
            int leftBegin = i * size;
            for (Long accountId : entrustAccounts) {
                if (leftBegin == noAccountGroups.size()) {
                    break;
                }

                List<TargetingSpecGroupBo> tempGroups = noAccountTargetingSpecGroups.get(accountId);
                if (null == tempGroups) {
                    tempGroups = new ArrayList<>();
                    noAccountTargetingSpecGroups.put(accountId, tempGroups);
                }
                tempGroups.add(noAccountGroups.get(leftBegin));
                leftBegin++;
            }
        }

        return noAccountTargetingSpecGroups;
    }

    private Map<String, TargetingSpecGroupBo> parseTargetingSpecGroups(List<TargetingSpecGroupBo> groups) throws BusinessException {
        int i = 0;
        Map<String, TargetingSpecGroupBo> map = new HashMap<>();
        for (TargetingSpecGroupBo group : groups) {
            group.setGroupId(CommonConstants.TMP_GROUPID_PREFIX + i);
            group.setStatus(PublishStatus.WAIT_PUPLISH.getCode());
            group.setPeople(0L);
            //跟据用户定位组生成TargetingSpec以及描述
            buildTargetingSpecsByGroup(group);
            map.put(CommonConstants.TMP_GROUPID_PREFIX + i, group);
            i++;
        }
        return map;
    }

    private void previewUserAudienceByAccounts(String batchCacheId, String userAudienceCacheId,
                                               Map<Long, List<TargetingSpecGroupBo>> accountTargetingSpecGroups, String accessToken) {
        EntrustAccountParam accountParam;
        for (Map.Entry<Long, List<TargetingSpecGroupBo>> entry : accountTargetingSpecGroups.entrySet()) {
            accountParam = new EntrustAccountParam();
            accountParam.setAccountId(entry.getKey().toString());
            accountParam.setAccessToken(accessToken);
            //根据账号发送用户定位请求
            targetUserAudienceByAccounts(batchCacheId, userAudienceCacheId, entry.getValue(), accountParam);
        }
    }

    private Long buildTargetingSpecsByGroup(TargetingSpecGroupBo tsg) throws BusinessException {
        FBTargetingSpecs fBTargetingSpecs = new FBTargetingSpecs();
        LocalTargetingSpecs localTargetingSpecs = new LocalTargetingSpecs();
        Set<TargetingSpecBo> targetingSpecs = tsg.getTargetingSpecBoes();
        String spec;
        Long fbAccountId = null;
        boolean hasLookLikeAudience = false;
        for(TargetingSpecBo bo : targetingSpecs)
        {
            if(TargetingType.LookalikeAudience.equals(bo.getType()) && !"{}".equals(bo.getSpec()))
                hasLookLikeAudience = true;
        }
        for (TargetingSpecBo targetingSpec : targetingSpecs) {
            spec = targetingSpec.getSpec();
            switch (targetingSpec.getType()) {
                case CustomAudience:
                    //自定义受众  这是老的先不删除
                    fbAccountId = parseCustomAudience(targetingSpec.getIndex(),
                            spec, fBTargetingSpecs, localTargetingSpecs);
                    tsg.setFbAccountId(fbAccountId);
                    break;
                case LookalikeAudience:
                    //受众
                    fbAccountId = parseLookalikeAudience(targetingSpec.getIndex(),
                            spec, fBTargetingSpecs, localTargetingSpecs);
                    tsg.setFbAccountId(fbAccountId);
                    break;
                case Platform:
                    Platform platform = JSON.parseObject(spec, Platform.class);
                    if (null == platform || null == platform.getType()) {
                        throw new BusinessException(ErrorType.INVALID_PLATFORM);
                    }
                    platform.setIndex(targetingSpec.getIndex());
                    localTargetingSpecs.setPlatform(platform);
                    Integer type = platform.getType();
                    String osPrefix;
                    String osPostfix = "_and_above";
                    if (UserOs.iOS.getCode() == type || type ==3) {
                        //IOS
                        osPrefix = "iOS_ver_";

                    } else {
                        //Android
                        osPrefix = "Android_ver_";
                    }
                    List<String> userOS = platform.getUserOS();
                    if (null != userOS && 0 < userOS.size()) {
                        List<String> fbUserOS = new ArrayList<>();
                        for (String os : userOS) {
                            fbUserOS.add(osPrefix + os + osPostfix);
                        }

                        fBTargetingSpecs.setUserOs(fbUserOS);
                    }

                    fBTargetingSpecs.setUserDevice(platform.getUserDevice());
                    break;
                case WirelessConnection:
                    List<Integer> wirelessConnections =
                            JSON.parseArray(spec, Integer.class);
                    localTargetingSpecs.setWirelessConnection(wirelessConnections);
                    if (null != wirelessConnections
                            && 0 < wirelessConnections.size()) {
                        List<String> fbWirelessConnection = new ArrayList<>();
                        for (Integer wirelessConnection : wirelessConnections) {
                            WirelessCarrier wirelessCarrier = WirelessCarrier.getWirelessCarrier(wirelessConnection);
                            if (WirelessCarrier.AllMobileUsers == wirelessCarrier){
                                continue;
                            } else {
                                fbWirelessConnection.add(WirelessCarrier.Wifi.getWirelessCarrier());
                            }
                        }
                        fBTargetingSpecs.setWirelessCarrier(fbWirelessConnection);
                    }
                    break;
                case Location:
                    if(hasLookLikeAudience)
                        break;
                    parseLocation(fBTargetingSpecs, localTargetingSpecs, spec, targetingSpec);
                    break;
                case Age:
                    Age age = JSON.parseObject(spec, Age.class);
                    age.setIndex(targetingSpec.getIndex());
                    localTargetingSpecs.setAge(age);
                    fBTargetingSpecs.setAgeMax(age.getAgeMax());
                    fBTargetingSpecs.setAgeMin(age.getAgeMin());
                    break;
                case Gender:
                    List<Integer> genders =
                            JSON.parseArray(spec, Integer.class);
                    LocalGender localGender = new LocalGender(targetingSpec.getIndex(), genders);
                    localTargetingSpecs.setGenders(localGender);
                    fBTargetingSpecs.setGenders(genders);
                    break;
                case Interests:
                    List<Interest> interests = JSON.parseArray(spec, Interest.class);
                    LocalInterest localInterest = new LocalInterest(targetingSpec.getIndex(), interests);
                    localTargetingSpecs.setInterests(localInterest);
                    fBTargetingSpecs.setInterests(interests);
                    break;
                case Connections:
                    LocalConnection localConnection =
                            JSON.parseObject(spec, LocalConnection.class);
                    localConnection.setIndex(targetingSpec.getIndex());
                    localTargetingSpecs.setLocalConnection(localConnection);
                    Connections connections = Connections.getConnections(localConnection.getType());
                    if (Connections.Connections == connections) {
                        fBTargetingSpecs.setConnections(localConnection.getConnections());
                    } else if (Connections.Excluded_connections == connections) {
                        fBTargetingSpecs.setExcludedConnections(localConnection.getConnections());
                    } else {
                        ;
                    }
                    break;
                case Languages:
                    List<Language> languages =
                            JSON.parseArray(spec, Language.class);
                    localTargetingSpecs.setLanguages(languages);
                    if (null != languages && 0 < languages.size()) {
                        List<Integer> locales = new ArrayList<>();
                        for (Language language : languages) {
                            locales.add(language.getId());
                        }
                        fBTargetingSpecs.setLocales(locales);
                    }
                    break;
                case MoreCategories:
                    List<BroadCategory> broadCategories =
                            JSON.parseArray(spec, BroadCategory.class);
                    localTargetingSpecs.setBroadCategories(broadCategories);
                    fBTargetingSpecs.setUserAdclusters(broadCategories);
                    break;
                case PageTypes:
                    List<Integer> pageTypes =
                            JSON.parseArray(spec, Integer.class);
                    LocalPageType localPageType = new LocalPageType(targetingSpec.getIndex(), pageTypes);
                    localTargetingSpecs.setPageTypes(localPageType);

                    if (null != pageTypes && 0 < pageTypes.size()) {
                        List<String> fbPageTypes = new ArrayList<>();
                        for (Integer pageType : pageTypes) {
                            fbPageTypes.add(PageType.getPageType(pageType).getPageTypeName());
                        }

                        fBTargetingSpecs.setPageTypes(fbPageTypes);
                    }

                    break;
                case Behavior:
                    List<Behavior> behaviors = JSON.parseArray(spec, Behavior.class);
                    localTargetingSpecs.setBehaviors(behaviors);
                    fBTargetingSpecs.setBehaviors(behaviors);
                    break;
                //v0.8.8 高级定位
                case NewInterestedIn:
                    //感情状况--性取向
                    parseInterestedIn(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case NewRelationshipStatus:
                    //感情状况--感情状况
                    parseRelationshipStatus(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case EducationStatuses:
                    //学历--教育程度
                    parseEducationStatuses(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case EducationMajors:
                    //学历 研究领域
                    parseEducationMajors(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case EducationSchools:
                    //学历 学校
                    parseEducationSchools(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case CollegeYears:
                    //学历 大学就读年份
                    parseCollegeYears(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case WorkEmployers:
                    //工作 雇主
                    parseWorkEmployers(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case WorkPositions:
                    //工作 职务
                    parseWorkPositions(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case Industries:
                    //工作 行业
                    parseIndustries(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case EthnicAffinity:
                    parseEthnicAffinities(spec, localTargetingSpecs, fBTargetingSpecs);
                    //族裔
                    break;
                case Generation:
                    //世代
                    parseGenerations(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case FamilyStatuses:
                    //父母
                    parseFamilyStatuses(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case Politics:
                    //政治（美国）
                    parsePolitics(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                case LifeEvents:
                    //生活纪事
                    parseLifeEvents(spec, localTargetingSpecs, fBTargetingSpecs);
                    break;
                default:
                    break;
            }
        }
        tsg.setTargetingSpecs(JSON.toJSONString(fBTargetingSpecs));
        tsg.setLocalTargetingSpecs(localTargetingSpecs);

        //构造用户定位描述
        FbTargetingSentencelines fbTargetingSentencelines = targetingSentenceLines(localTargetingSpecs);
        tsg.setTargetingDescriptions(fbTargetingSentencelines.getTargetingsentencelines());
        return fbAccountId;
    }

    private void parseLocation(FBTargetingSpecs fBTargetingSpecs, LocalTargetingSpecs localTargetingSpecs, String spec, TargetingSpecBo targetingSpec) {
        //解析LocalLocation
        LocalLocation inputLocation = JSON.parseObject(spec, LocalLocation.class);

        //本地包括地区
        LocalLocation localLocation = new LocalLocation();
        //本地不包括地区
        LocalLocation excludeLocation = new LocalLocation();

        //fb 包括地区
        Location fbLocation = new Location();
        //fb 不包括地区
        Location excludeFbLocation = new Location();

        handleCountries(inputLocation.getCountries(), localLocation, excludeLocation, fbLocation, excludeFbLocation);

        handleCities(inputLocation, localLocation, excludeLocation, fbLocation, excludeFbLocation);

        handleLocationType(inputLocation, fbLocation);

        localLocation.setIndex(targetingSpec.getIndex());
        localLocation.setLocationType(inputLocation.getLocationType());
        localTargetingSpecs.setLocalLocation(localLocation);
        localTargetingSpecs.setExcludeLocation(excludeLocation);
        fBTargetingSpecs.setGeoLocations(fbLocation);
        fBTargetingSpecs.setExcludedGeoLocations(excludeFbLocation);
    }

    private void handleLocationType(LocalLocation inputLocation, Location fbLocation) {
        Integer locationType = inputLocation.getLocationType();
        List<String> fbLocationType = new ArrayList<>();
        if (null == locationType) {
            fbLocationType.add(LocationType.Home.getLocationType());
        } else {
            LocationType locationTypeE = LocationType.getLocationType(locationType);
            switch (locationTypeE) {
                case All:
                    fbLocationType.add(LocationType.Recent.getLocationType());
                    fbLocationType.add(LocationType.Home.getLocationType());
                    break;
                case Recent:
                    fbLocationType.add(LocationType.Recent.getLocationType());
                    break;
                case Travel_in:
                    fbLocationType.add(LocationType.Travel_in.getLocationType());
                    break;
                case Home:
                default:
                    fbLocationType.add(LocationType.Home.getLocationType());
                    break;
            }
        }
        fbLocation.setLocationTypes(fbLocationType);
    }

    private void handleCities(LocalLocation inputLocation, LocalLocation localLocation,
                              LocalLocation excludeLocation, Location fbLocation, Location excludeFbLocation) {
        List<City> cities = inputLocation.getCities();

        if (null != cities && 0 < cities.size()) {
            List<FbLocation> fbCities;
            List<City> localCities;
            FbLocation fb;
            for (City city : cities) {
                if (null == city.getIsClude() || city.getIsClude()) {
                    //包括
                    fbCities = fbLocation.getCities();
                    localCities = localLocation.getCities();
                    if (null == fbCities) {
                        fbCities = new ArrayList<>();
                        fbLocation.setCities(fbCities);
                    }

                    if (null == localCities) {
                        localCities = new ArrayList<>();
                        localLocation.setCities(localCities);
                    }
                } else {
                    //不包括
                    fbCities = excludeFbLocation.getCities();
                    localCities = excludeLocation.getCities();
                    if (null == fbCities) {
                        fbCities = new ArrayList<>();
                        excludeFbLocation.setCities(fbCities);
                    }
                    if (null == localCities) {
                        localCities = new ArrayList<>();
                        excludeLocation.setCities(localCities);
                    }
                }

                fb = new FbLocation();
                fb.setKey(city.getKey());
                fb.setRadius(20);
                fb.setDistanceUnit("kilometer");
                fbCities.add(fb);
                localCities.add(city);
            }
        }
    }

    private void handleCountries(List<Country> countries, LocalLocation localLocation,
                                 LocalLocation excludeLocation, Location fbLocation, Location excludeFbLocation) {
        if (null != countries && 0 < countries.size()) {
            List<String> countryCodes;
            List<Country> localCountries;
            for (Country country : countries) {
                if (null == country.getIsClude() || country.getIsClude()) {
                    localCountries = localLocation.getCountries();
                    countryCodes = fbLocation.getCountries();
                    //包括
                    if (null == localCountries) {
                        localCountries = new ArrayList<>();
                        localLocation.setCountries(localCountries);
                    }

                    if (null == countryCodes) {
                        countryCodes = new ArrayList<>();
                        fbLocation.setCountries(countryCodes);
                    }
                } else {
                    //不包括
                    localCountries = excludeLocation.getCountries();
                    countryCodes = excludeFbLocation.getCountries();
                    //包括
                    if (null == localCountries) {
                        localCountries = new ArrayList<>();
                        excludeLocation.setCountries(localCountries);
                    }

                    if (null == countryCodes) {
                        countryCodes = new ArrayList<>();
                        excludeFbLocation.setCountries(countryCodes);
                    }
                }

                localCountries.add(country);
                countryCodes.add(country.getCountryCode());
            }
        }
    }

    private void parseLifeEvents(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<LifeEvent> lifeEvents = JSON.parseArray(spec, LifeEvent.class);
        if (CollectionUtils.isEmpty(lifeEvents)) {
            return;
        }
        localTargetingSpecs.setLifeEvents(lifeEvents);
        fBTargetingSpecs.setLifeEvents(lifeEvents);
    }

    private void parsePolitics(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<Politic> politics = JSON.parseArray(spec, Politic.class);
        if (CollectionUtils.isEmpty(politics)) {
            return;
        }
        localTargetingSpecs.setPolitics(politics);
        fBTargetingSpecs.setPolitics(politics);
    }

    private void parseFamilyStatuses(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<FamilyStatus> familyStatuses = JSON.parseArray(spec, FamilyStatus.class);
        if (CollectionUtils.isEmpty(familyStatuses)) {
            return;
        }
        localTargetingSpecs.setFamilyStatuses(familyStatuses);
        fBTargetingSpecs.setFamilyStatuses(familyStatuses);
    }

    private void parseGenerations(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<Generation> generations = JSON.parseArray(spec, Generation.class);
        if (CollectionUtils.isEmpty(generations)) {
            return;
        }
        localTargetingSpecs.setGenerations(generations);
        fBTargetingSpecs.setGenerations(generations);
    }

    private void parseEthnicAffinities(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<EthnicAffinity> ethnicAffinities = JSON.parseArray(spec, EthnicAffinity.class);
        if (CollectionUtils.isEmpty(ethnicAffinities)) {
            return;
        }
        localTargetingSpecs.setEthnicAffinities(ethnicAffinities);
        fBTargetingSpecs.setEthnicAffinities(ethnicAffinities);
    }

    private void parseIndustries(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<Industry> industries = JSON.parseArray(spec, Industry.class);
        if (CollectionUtils.isEmpty(industries)) {
            return;
        }
        localTargetingSpecs.setIndustries(industries);
        fBTargetingSpecs.setIndustries(industries);
    }

    private void parseWorkPositions(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<WorkPosition> workPositions = JSON.parseArray(spec, WorkPosition.class);
        if (CollectionUtils.isEmpty(workPositions)) {
            return;
        }
        localTargetingSpecs.setWorkPositions(workPositions);
        fBTargetingSpecs.setWorkPositions(workPositions);
    }

    private void parseWorkEmployers(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<WorkEmployer> workEmployers = JSON.parseArray(spec, WorkEmployer.class);
        if (CollectionUtils.isEmpty(workEmployers)) {
            return;
        }
        localTargetingSpecs.setWorkEmployers(workEmployers);
        fBTargetingSpecs.setWorkEmployers(workEmployers);
    }

    private void parseCollegeYears(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        CollegeYear collegeYear = JSON.parseObject(spec, CollegeYear.class);
        if (null == collegeYear || null == collegeYear.getStart()
                || null == collegeYear.getEnd() || collegeYear.getStart() > collegeYear.getEnd()) {
            return;
        }

        localTargetingSpecs.setCollegeYear(collegeYear);
        Long start = collegeYear.getStart();
        Long end = collegeYear.getEnd();
        List<Long> collegeYears = new ArrayList<>();
        for (Long i = start; i <= end; i++) {
            collegeYears.add(i);
        }
        fBTargetingSpecs.setCollegeYear(collegeYears);
    }

    private void parseEducationSchools(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<EducationSchool> educationSchools = JSON.parseArray(spec, EducationSchool.class);
        if (CollectionUtils.isEmpty(educationSchools)) {
            return;
        }
        localTargetingSpecs.setEducationSchools(educationSchools);
        fBTargetingSpecs.setEducationSchools(educationSchools);
    }

    private void parseEducationMajors(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<EducationMajor> educationMajors = JSON.parseArray(spec, EducationMajor.class);
        if (CollectionUtils.isEmpty(educationMajors)) {
            return;
        }
        localTargetingSpecs.setEducationMajors(educationMajors);
        fBTargetingSpecs.setEducationMajors(educationMajors);
    }

    private void parseEducationStatuses(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<EducationStatus> educationStatuses = JSON.parseArray(spec, EducationStatus.class);
        if (CollectionUtils.isEmpty(educationStatuses)) {
            return;
        }
        localTargetingSpecs.setEducationStatuses(educationStatuses);

        List<Integer> fbEducationStatus = new ArrayList<>();
        for (EducationStatus educationStatus : educationStatuses) {
            fbEducationStatus.add(educationStatus.getId());
        }

        fBTargetingSpecs.setEducationStatuses(fbEducationStatus);
    }

    private void parseRelationshipStatus(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<RelationshipStatus> relationshipStatuses
                = JSON.parseArray(spec, RelationshipStatus.class);
        if (CollectionUtils.isEmpty(relationshipStatuses)) {
            return;
        }
        localTargetingSpecs.setNewRelationshipStatus(relationshipStatuses);

        List<Integer> fbRelationshipStatus = new ArrayList<>();
        for (RelationshipStatus relationshipStatus : relationshipStatuses) {
            fbRelationshipStatus.add(relationshipStatus.getId());
        }

        fBTargetingSpecs.setRelationshipStatuses(fbRelationshipStatus);
    }

    private void parseInterestedIn(String spec, LocalTargetingSpecs localTargetingSpecs, FBTargetingSpecs fBTargetingSpecs) {
        List<InterestedIn> interestedIns = JSON.parseArray(spec, InterestedIn.class);
        if (CollectionUtils.isEmpty(interestedIns)) {
            return;
        }
        localTargetingSpecs.setNewInterestedIn(interestedIns);

        List<Integer> fbInterestedIn = new ArrayList<>();
        for (InterestedIn interestedIn : interestedIns) {
            fbInterestedIn.add(interestedIn.getId());
        }

        fBTargetingSpecs.setInterestedIn(fbInterestedIn);
    }


    private Long parseCustomAudience(Long index, String spec,
                                     FBTargetingSpecs fBTargetingSpecs, LocalTargetingSpecs localTargetingSpecs) {
        LocalCustomAudience localCustomAudience =
                JSON.parseObject(spec, LocalCustomAudience.class);
        if (null == localCustomAudience || null == localCustomAudience.getFbAccountId()
                || CollectionUtils.isEmpty(localCustomAudience.getCustomAudiences())) {
            return null;
        }

        List<CustomAudience> customAudiences = localCustomAudience.getCustomAudiences();
        //不包含
        List<CustomAudience> excludedCustomAudiences = new ArrayList<>();
        //包含
        List<CustomAudience> includedCustomAudiences = new ArrayList<>();
        BuildCacheUtils.customAudienceAdd(customAudiences, excludedCustomAudiences, includedCustomAudiences);

        if (!CollectionUtils.isEmpty(excludedCustomAudiences)) {
            fBTargetingSpecs.setExcludedCustomAudiences(excludedCustomAudiences);
        }

        if (!CollectionUtils.isEmpty(includedCustomAudiences)) {
            fBTargetingSpecs.setCustomAudiences(includedCustomAudiences);

        }

        localTargetingSpecs.setFbAccountId(localCustomAudience.getFbAccountId());
        String fbAccountName = StringUtils.isEmpty(localCustomAudience.getFbAccountName())
                ? localCustomAudience.getFbAccountId().toString() : localCustomAudience.getFbAccountName();
        localTargetingSpecs.setCustomAudiences(new LocalCustomAudience(index,
                localCustomAudience.getFbAccountId(), fbAccountName,
                includedCustomAudiences, excludedCustomAudiences));

        return localCustomAudience.getFbAccountId();
    }


    /**
     * 生成用户定位解析 相似受众
     * TODO 每组相似受众只能对应其填入的地区
     * @return  fbaccountid
     */
    private Long parseLookalikeAudience(Long index, String spec,
                                     FBTargetingSpecs fBTargetingSpecs, LocalTargetingSpecs localTargetingSpecs) {
        LocalCustomAudience localCustomAudience =
                JSON.parseObject(spec, LocalCustomAudience.class);
        if (null == localCustomAudience || null == localCustomAudience.getFbAccountId()
                || CollectionUtils.isEmpty(localCustomAudience.getCustomAudiences())) {
            return null;
        }

        List<CustomAudience> customAudiences = localCustomAudience.getCustomAudiences();
        //不包含
        List<CustomAudience> excludedCustomAudiences = new ArrayList<>();
        //包含
        List<CustomAudience> includedCustomAudiences = new ArrayList<>();
        for (int m = 0; m < customAudiences.size(); m++) {
            if(m == 0){
                if (null != customAudiences.get(m).getIsClude() && customAudiences.get(m).getIsClude()) {
                    includedCustomAudiences.add(customAudiences.get(m));
                } else {
                    excludedCustomAudiences.add(customAudiences.get(m));
                }
                customAudiences.get(m).setIsClude(null);
            }
        }

        if (!CollectionUtils.isEmpty(excludedCustomAudiences)) {
            fBTargetingSpecs.setExcludedCustomAudiences(excludedCustomAudiences);
        }

        if (!CollectionUtils.isEmpty(includedCustomAudiences)) {
            fBTargetingSpecs.setCustomAudiences(includedCustomAudiences);

        }

        //本地包括地区
        LocalLocation localLocation = new LocalLocation();
        //fb 包括地区
        Location fbLocation = new Location();
        List<String> countryCodes = new ArrayList<>();
        countryCodes.add(localCustomAudience.getCountryCode());
        List<String> fbLocationType = new ArrayList<>();
        fbLocationType.add(LocationType.Recent.getLocationType());
        fbLocationType.add(LocationType.Home.getLocationType());
        fbLocation.setCountries(countryCodes);
        fbLocation.setLocationTypes(fbLocationType);
        List<Country> localCountries = new ArrayList<>();
        Country country = new Country();
        country.setCountryCode(localCustomAudience.getCountryCode());
        country.setName(localCustomAudience.getCountryName().split("\\(")[0]);
        country.setIsClude(true);
        localCountries.add(country);
        localLocation.setIndex(localCustomAudience.getDataIndex());
        localLocation.setLocationType(LocationType.All.getCode());
        localLocation.setCountries(localCountries);
        localTargetingSpecs.setLocalLocation(localLocation);
        fBTargetingSpecs.setGeoLocations(fbLocation);

        localTargetingSpecs.setFbAccountId(localCustomAudience.getFbAccountId());
        LocalCustomAudience localCustomAudience1 = new LocalCustomAudience();
        localCustomAudience1.setIndex(index);
        localCustomAudience1.setFbAccountId(localCustomAudience.getFbAccountId());
        String fbAccountName = StringUtils.isEmpty(localCustomAudience.getFbAccountName())
                ? localCustomAudience.getFbAccountId().toString() : localCustomAudience.getFbAccountName();
        localCustomAudience1.setFbAccountName(fbAccountName);
        localCustomAudience1.setCustomAudiences(includedCustomAudiences);
        localCustomAudience1.setExcludedCustomAudiences(excludedCustomAudiences);
        localTargetingSpecs.setCustomAudiences(localCustomAudience1);

        return localCustomAudience.getFbAccountId();
    }

    private FbTargetingSentencelines targetingSentenceLines(LocalTargetingSpecs localTargetingSpecs) {
        FbTargetingSentencelines fbTargetingSentencelines = new FbTargetingSentencelines();
        List<TargetingDescriptionBo> targetingDescriptionBoes = new ArrayList<>();
        // 自定义受众
        List<TargetingDescriptionBo> customAudiencesTargetingDescriptionBo = buildCustomAudienceTargetingDescriptionBo(
                localTargetingSpecs.getCustomAudiences());
        if (!CollectionUtils.isEmpty(customAudiencesTargetingDescriptionBo)) {
            targetingDescriptionBoes.addAll(customAudiencesTargetingDescriptionBo);
        }

        //地区	显示输入的内容，多个地区间用英文逗号分隔
        TargetingDescriptionBo countryTargetingDescriptionBo = buildCountryTargetingDescriptionBo(localTargetingSpecs.getLocalLocation());
        if (null != countryTargetingDescriptionBo) {
            targetingDescriptionBoes.add(countryTargetingDescriptionBo);
        }

        //地区	排除地区
        TargetingDescriptionBo excludeCountryTargetingDescriptionBo = buildExcludeCountryTargetingDescriptionBo(localTargetingSpecs.getExcludeLocation());
        if (null != excludeCountryTargetingDescriptionBo) {
            targetingDescriptionBoes.add(excludeCountryTargetingDescriptionBo);
        }

        // 年龄	格式举例：17-30  如果年龄上限是no max,则显示65+；如果年龄上限等于年龄下限，则显示年龄下限即可
        TargetingDescriptionBo ageTargetingDescriptionBo = buildAgeTargetingDescriptionBo(localTargetingSpecs.getAge());
        if (null != ageTargetingDescriptionBo) {
            targetingDescriptionBoes.add(ageTargetingDescriptionBo);
        }

        //性别	显示选项名称。选择all不显示该字段
        TargetingDescriptionBo genderTargetingDescriptionBo = buildGenderTargetingDescriptionBo(localTargetingSpecs.getGenders());
        if (null != genderTargetingDescriptionBo) {
            targetingDescriptionBoes.add(genderTargetingDescriptionBo);
        }

        //兴趣	显示输入的兴趣的名称，多个兴趣间用中文逗号分隔。无输入则不显示该字段
        TargetingDescriptionBo interestTargetingDescriptionBo = buildInterestTargetingDescriptionBo(localTargetingSpecs.getInterests());
        if (null != interestTargetingDescriptionBo) {
            targetingDescriptionBoes.add(interestTargetingDescriptionBo);
        }

        //行为	显示输入的兴趣的名称，多个兴趣间用中文逗号分隔。无输入则不显示该字段
        TargetingDescriptionBo behaviorsDescriptionBo = buildBehaviorsTargetingDescriptionBo(localTargetingSpecs.getBehaviors());
        if (null != behaviorsDescriptionBo) {
            targetingDescriptionBoes.add(behaviorsDescriptionBo);
        }

        //联系	显示选项名称。无输入则不显示该字段
        TargetingDescriptionBo connectionTargetingDescriptionBo = buildConnectionTargetingDescriptionBo(
                localTargetingSpecs.getLocalConnection());
        if (null != connectionTargetingDescriptionBo) {
            targetingDescriptionBoes.add(connectionTargetingDescriptionBo);
        }

        //性取向	显示选项名称。选择all不显示该字段
        TargetingDescriptionBo interestedInTargetingDescriptionBo = buildInterestedInTargetingDescriptionBo(
                localTargetingSpecs.getInterestedIn());
        if (null != interestedInTargetingDescriptionBo) {
            targetingDescriptionBoes.add(interestedInTargetingDescriptionBo);
        }

        //婚姻状况	显示选项名称，多个选项间用英文逗号分隔。不选择不显示该字段。
        TargetingDescriptionBo relationshipTargetingDescriptionBo = buildRelationshipTargetingDescriptionBo(
                localTargetingSpecs.getRelationshipStatus());
        if (null != relationshipTargetingDescriptionBo) {
            targetingDescriptionBoes.add(relationshipTargetingDescriptionBo);
        }

        //语言	显示输入的内容，多个语言间用英文逗号分隔。无输入不显示该字段。
        TargetingDescriptionBo languagesTargetingDescriptionBo = buildLanguagesTargetingDescriptionBo(
                localTargetingSpecs.getLanguages());
        if (null != languagesTargetingDescriptionBo) {
            targetingDescriptionBoes.add(languagesTargetingDescriptionBo);
        }

        //更多类型	显示类型的名称，多个类型间用中文逗号分隔。无输入不显示该字段。
        TargetingDescriptionBo broadCategoriesTargetingDescriptionBo = buildBroadCategoriesTargetingDescriptionBo(
                localTargetingSpecs.getBroadCategories());
        if (null != broadCategoriesTargetingDescriptionBo) {
            targetingDescriptionBoes.add(broadCategoriesTargetingDescriptionBo);
        }

        //增加版位	显示动态信息，第三方应用程序
        TargetingDescriptionBo pageTypeBo = buildPageTypeTargetingDescriptionBo(
                localTargetingSpecs.getPageTypes());
        if (null != pageTypeBo) {
            targetingDescriptionBoes.add(pageTypeBo);
        }


        //设备	显示平台中的设备名称，多个选项用英文逗号分隔
        TargetingDescriptionBo userDeviceTargetingDescriptionBo = buildUserDeviceTargetingDescriptionBo(
                localTargetingSpecs.getPlatform());
        if (null != userDeviceTargetingDescriptionBo) {
            targetingDescriptionBoes.add(userDeviceTargetingDescriptionBo);
        }

        //操作系统	显示平台中的系统和版本。举例：iOS版本2.0或更高
        TargetingDescriptionBo userOSTargetingDescriptionBo = buildUserOSTargetingDescriptionBo(
                localTargetingSpecs.getPlatform());
        if (null != userOSTargetingDescriptionBo) {
            targetingDescriptionBoes.add(userOSTargetingDescriptionBo);
        }

        //无线连接	显示选项名称
        TargetingDescriptionBo wirelessConnectionTargetingDescriptionBo = buildWirelessConnectionTargetingDescriptionBo(
                localTargetingSpecs.getWirelessConnection());
        if (null != wirelessConnectionTargetingDescriptionBo) {
            targetingDescriptionBoes.add(wirelessConnectionTargetingDescriptionBo);
        }

        //感情状况--性取向
        TargetingDescriptionBo newInterestedInTargetingDescriptionBo = buildNewInterestedInTargetingDescriptionBo(
                localTargetingSpecs.getNewInterestedIn());
        if (null != newInterestedInTargetingDescriptionBo) {
            targetingDescriptionBoes.add(newInterestedInTargetingDescriptionBo);
        }

        //感情状况--感情状况
        TargetingDescriptionBo newRelationshipStatusTargetingDescriptionBo = buildNewRelationshipStatusTargetingDescriptionBo(
                localTargetingSpecs.getNewRelationshipStatus());
        if (null != newRelationshipStatusTargetingDescriptionBo) {
            targetingDescriptionBoes.add(newRelationshipStatusTargetingDescriptionBo);
        }

        //学历--教育程度
        TargetingDescriptionBo educationStatusesTargetingDescriptionBo = buildEducationStatusesTargetingDescriptionBo(
                localTargetingSpecs.getEducationStatuses());
        if (null != educationStatusesTargetingDescriptionBo) {
            targetingDescriptionBoes.add(educationStatusesTargetingDescriptionBo);
        }

        //学历 研究领域
        TargetingDescriptionBo educationMajorsTargetingDescriptionBo = buildEducationMajorsTargetingDescriptionBo(
                localTargetingSpecs.getEducationMajors());
        if (null != educationMajorsTargetingDescriptionBo) {
            targetingDescriptionBoes.add(educationMajorsTargetingDescriptionBo);
        }

        //学历 学校
        TargetingDescriptionBo educationSchoolsTargetingDescriptionBo = buildEducationSchoolsTargetingDescriptionBo(
                localTargetingSpecs.getEducationSchools());
        if (null != educationSchoolsTargetingDescriptionBo) {
            targetingDescriptionBoes.add(educationSchoolsTargetingDescriptionBo);
        }

        //学历 大学就读年份
        TargetingDescriptionBo collegeYearTargetingDescriptionBo = buildCollegeYearsTargetingDescriptionBo(
                localTargetingSpecs.getCollegeYear());
        if (null != collegeYearTargetingDescriptionBo) {
            targetingDescriptionBoes.add(collegeYearTargetingDescriptionBo);
        }

        //工作 雇主
        TargetingDescriptionBo workEmployersTargetingDescriptionBo = buildWorkEmployersTargetingDescriptionBo(
                localTargetingSpecs.getWorkEmployers());
        if (null != workEmployersTargetingDescriptionBo) {
            targetingDescriptionBoes.add(workEmployersTargetingDescriptionBo);
        }

        //工作 职务
        TargetingDescriptionBo workPositionsTargetingDescriptionBo = buildWorkPositionsTargetingDescriptionBo(
                localTargetingSpecs.getWorkPositions());
        if (null != workPositionsTargetingDescriptionBo) {
            targetingDescriptionBoes.add(workPositionsTargetingDescriptionBo);
        }

        //工作 行业
        TargetingDescriptionBo industriesTargetingDescriptionBo = buildIndustriesTargetingDescriptionBo(
                localTargetingSpecs.getIndustries());
        if (null != industriesTargetingDescriptionBo) {
            targetingDescriptionBoes.add(industriesTargetingDescriptionBo);
        }

        //族裔
        TargetingDescriptionBo ethnicAffinitiesTargetingDescriptionBo = buildEthnicAffinitiesTargetingDescriptionBo(
                localTargetingSpecs.getEthnicAffinities());
        if (null != ethnicAffinitiesTargetingDescriptionBo) {
            targetingDescriptionBoes.add(ethnicAffinitiesTargetingDescriptionBo);
        }

        //世代
        TargetingDescriptionBo generationsTargetingDescriptionBo = buildGenerationsTargetingDescriptionBo(
                localTargetingSpecs.getGenerations());
        if (null != generationsTargetingDescriptionBo) {
            targetingDescriptionBoes.add(generationsTargetingDescriptionBo);
        }

        //父母
        TargetingDescriptionBo familyStatusesTargetingDescriptionBo = buildFamilyStatusesTargetingDescriptionBo(
                localTargetingSpecs.getFamilyStatuses());
        if (null != familyStatusesTargetingDescriptionBo) {
            targetingDescriptionBoes.add(familyStatusesTargetingDescriptionBo);
        }

        //政治（美国）
        TargetingDescriptionBo politicsTargetingDescriptionBo = buildPoliticsTargetingDescriptionBo(
                localTargetingSpecs.getPolitics());
        if (null != politicsTargetingDescriptionBo) {
            targetingDescriptionBoes.add(politicsTargetingDescriptionBo);
        }

        //生活纪事
        TargetingDescriptionBo lifeEventsTargetingDescriptionBo = buildLifeEventsTargetingDescriptionBo(
                localTargetingSpecs.getLifeEvents());
        if (null != lifeEventsTargetingDescriptionBo) {
            targetingDescriptionBoes.add(lifeEventsTargetingDescriptionBo);
        }

        fbTargetingSentencelines.setTargetingsentencelines(targetingDescriptionBoes);
        return fbTargetingSentencelines;
    }

    private TargetingDescriptionBo buildExcludeCountryTargetingDescriptionBo(LocalLocation excludeLocation) {
        if (null == excludeLocation || (CollectionUtils.isEmpty(excludeLocation.getCities())
                && CollectionUtils.isEmpty(excludeLocation.getCountries()))) {
            return null;
        }

        TargetingDescriptionBo countryTargetingDescriptionBo = new TargetingDescriptionBo();
        countryTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_EXCLUDE_LOCATION"));

        List<String> children = buildLocationDescription(excludeLocation);
        countryTargetingDescriptionBo.setChildren(children);

        return countryTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildLifeEventsTargetingDescriptionBo(List<LifeEvent> lifeEvents) {
        if (null == lifeEvents || CollectionUtils.isEmpty(lifeEvents)) {
            return null;
        }

        TargetingDescriptionBo lifeEventsTargetingDescriptionBo = new TargetingDescriptionBo();
        lifeEventsTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_LIFE_EVENT"));

        StringBuilder lifeEventsSb = new StringBuilder();
        boolean isFirst = true;
        for (LifeEvent lifeEvent : lifeEvents) {
            if (!isFirst) {
                lifeEventsSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            lifeEventsSb.append(lifeEvent.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(lifeEventsSb.toString());
        lifeEventsTargetingDescriptionBo.setChildren(children);

        return lifeEventsTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildPoliticsTargetingDescriptionBo(List<Politic> politics) {
        if (null == politics || CollectionUtils.isEmpty(politics)) {
            return null;
        }

        TargetingDescriptionBo politicTargetingDescriptionBo = new TargetingDescriptionBo();
        politicTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_POLITIC"));

        StringBuilder politicSb = new StringBuilder();
        boolean isFirst = true;
        for (Politic politic : politics) {
            if (!isFirst) {
                politicSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            politicSb.append(politic.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(politicSb.toString());
        politicTargetingDescriptionBo.setChildren(children);

        return politicTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildFamilyStatusesTargetingDescriptionBo(List<FamilyStatus> familyStatuses) {
        if (null == familyStatuses || CollectionUtils.isEmpty(familyStatuses)) {
            return null;
        }

        TargetingDescriptionBo familyStatusesTargetingDescriptionBo = new TargetingDescriptionBo();
        familyStatusesTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_FAMILY"));

        StringBuilder familyStatusesSb = new StringBuilder();
        boolean isFirst = true;
        for (FamilyStatus familyStatus : familyStatuses) {
            if (!isFirst) {
                familyStatusesSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            familyStatusesSb.append(familyStatus.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(familyStatusesSb.toString());
        familyStatusesTargetingDescriptionBo.setChildren(children);

        return familyStatusesTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildGenerationsTargetingDescriptionBo(List<Generation> generations) {
        if (null == generations || CollectionUtils.isEmpty(generations)) {
            return null;
        }

        TargetingDescriptionBo generationsTargetingDescriptionBo = new TargetingDescriptionBo();
        generationsTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_GENERATIONS"));

        StringBuilder generationsSb = new StringBuilder();
        boolean isFirst = true;
        for (Generation generation : generations) {
            if (!isFirst) {
                generationsSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            generationsSb.append(generation.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(generationsSb.toString());
        generationsTargetingDescriptionBo.setChildren(children);

        return generationsTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildEthnicAffinitiesTargetingDescriptionBo(List<EthnicAffinity> ethnicAffinities) {
        if (null == ethnicAffinities || CollectionUtils.isEmpty(ethnicAffinities)) {
            return null;
        }

        TargetingDescriptionBo ethnicAffinitiesTargetingDescriptionBo = new TargetingDescriptionBo();
        ethnicAffinitiesTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_ETHNIC_AFFINITIES"));

        StringBuilder ethnicAffinitiesSb = new StringBuilder();
        boolean isFirst = true;
        for (EthnicAffinity ethnicAffinity : ethnicAffinities) {
            if (!isFirst) {
                ethnicAffinitiesSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            ethnicAffinitiesSb.append(ethnicAffinity.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(ethnicAffinitiesSb.toString());
        ethnicAffinitiesTargetingDescriptionBo.setChildren(children);

        return ethnicAffinitiesTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildIndustriesTargetingDescriptionBo(List<Industry> industries) {
        if (null == industries || CollectionUtils.isEmpty(industries)) {
            return null;
        }

        TargetingDescriptionBo industriesTargetingDescriptionBo = new TargetingDescriptionBo();
        industriesTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_INDUSTRY"));

        StringBuilder industriesSb = new StringBuilder();
        boolean isFirst = true;
        for (Industry industry : industries) {
            if (!isFirst) {
                industriesSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            industriesSb.append(industry.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(industriesSb.toString());
        industriesTargetingDescriptionBo.setChildren(children);

        return industriesTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildWorkPositionsTargetingDescriptionBo(List<WorkPosition> workPositions) {
        if (null == workPositions || CollectionUtils.isEmpty(workPositions)) {
            return null;
        }

        TargetingDescriptionBo workPositionsTargetingDescriptionBo = new TargetingDescriptionBo();
        workPositionsTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_WORK_POSITION"));

        StringBuilder workPositionSb = new StringBuilder();
        boolean isFirst = true;
        for (WorkPosition workPosition : workPositions) {
            if (!isFirst) {
                workPositionSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            workPositionSb.append(workPosition.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(workPositionSb.toString());
        workPositionsTargetingDescriptionBo.setChildren(children);

        return workPositionsTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildWorkEmployersTargetingDescriptionBo(List<WorkEmployer> workEmployers) {
        if (null == workEmployers || CollectionUtils.isEmpty(workEmployers)) {
            return null;
        }

        TargetingDescriptionBo workEmployersTargetingDescriptionBo = new TargetingDescriptionBo();
        workEmployersTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_WORK_EMPLOYER"));

        StringBuilder workEmployersSb = new StringBuilder();
        boolean isFirst = true;
        for (WorkEmployer workEmployer : workEmployers) {
            if (!isFirst) {
                workEmployersSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            workEmployersSb.append(workEmployer.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(workEmployersSb.toString());
        workEmployersTargetingDescriptionBo.setChildren(children);

        return workEmployersTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildCollegeYearsTargetingDescriptionBo(CollegeYear collegeYear) {
        if (null == collegeYear || null == collegeYear.getStart()
                || null == collegeYear.getEnd() || collegeYear.getStart() > collegeYear.getEnd()) {
            return null;
        }


        TargetingDescriptionBo collegeYearsTargetingDescriptionBo = new TargetingDescriptionBo();
        collegeYearsTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_COLLEGE_YEAR"));
        String collegeYears = collegeYear.getStart() + CommonConstants.SYMBOL_LINE + collegeYear.getEnd();

        List<String> children = new ArrayList<>();
        children.add(collegeYears);
        collegeYearsTargetingDescriptionBo.setChildren(children);

        return collegeYearsTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildEducationSchoolsTargetingDescriptionBo(List<EducationSchool> educationSchools) {
        if (null == educationSchools || CollectionUtils.isEmpty(educationSchools)) {
            return null;
        }

        TargetingDescriptionBo educatieonSchoolsTargetingDescriptionBo = new TargetingDescriptionBo();
        educatieonSchoolsTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_EDUCATION_SCHOOL"));

        StringBuilder educatieonSchoolsSb = new StringBuilder();
        boolean isFirst = true;
        for (EducationSchool educationSchool : educationSchools) {
            if (!isFirst) {
                educatieonSchoolsSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            educatieonSchoolsSb.append(educationSchool.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(educatieonSchoolsSb.toString());
        educatieonSchoolsTargetingDescriptionBo.setChildren(children);

        return educatieonSchoolsTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildEducationMajorsTargetingDescriptionBo(List<EducationMajor> educationMajors) {
        if (null == educationMajors || CollectionUtils.isEmpty(educationMajors)) {
            return null;
        }

        TargetingDescriptionBo educationMajorsTargetingDescriptionBo = new TargetingDescriptionBo();
        educationMajorsTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_EDUCATION_MAJOR"));

        StringBuilder educationMajorsSb = new StringBuilder();
        boolean isFirst = true;
        for (EducationMajor educationMajor : educationMajors) {
            if (!isFirst) {
                educationMajorsSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            educationMajorsSb.append(educationMajor.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(educationMajorsSb.toString());
        educationMajorsTargetingDescriptionBo.setChildren(children);

        return educationMajorsTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildEducationStatusesTargetingDescriptionBo(List<EducationStatus> educationStatuses) {
        if (null == educationStatuses || CollectionUtils.isEmpty(educationStatuses)) {
            return null;
        }

        TargetingDescriptionBo educationStatusesTargetingDescriptionBo = new TargetingDescriptionBo();
        educationStatusesTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_EDUCATION_STATUS"));

        StringBuilder educationStatusesSb = new StringBuilder();
        boolean isFirst = true;
        for (EducationStatus educationStatus : educationStatuses) {
            if (!isFirst) {
                educationStatusesSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            educationStatusesSb.append(educationStatus.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(educationStatusesSb.toString());
        educationStatusesTargetingDescriptionBo.setChildren(children);

        return educationStatusesTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildNewRelationshipStatusTargetingDescriptionBo(List<RelationshipStatus> newRelationshipStatus) {
        if (null == newRelationshipStatus || CollectionUtils.isEmpty(newRelationshipStatus)) {
            return null;
        }

        TargetingDescriptionBo newRelationshipStatusTargetingDescriptionBo = new TargetingDescriptionBo();
        newRelationshipStatusTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_RELATIONSHIP_STATUS"));

        StringBuilder newRelationshipStatusSb = new StringBuilder();
        boolean isFirst = true;
        for (RelationshipStatus relationshipStatus : newRelationshipStatus) {
            if (!isFirst) {
                newRelationshipStatusSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            newRelationshipStatusSb.append(relationshipStatus.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(newRelationshipStatusSb.toString());
        newRelationshipStatusTargetingDescriptionBo.setChildren(children);

        return newRelationshipStatusTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildNewInterestedInTargetingDescriptionBo(List<InterestedIn> newInterestedIn) {
        if (null == newInterestedIn || CollectionUtils.isEmpty(newInterestedIn)) {
            return null;
        }

        TargetingDescriptionBo newInterestedInTargetingDescriptionBo = new TargetingDescriptionBo();
        newInterestedInTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_INTERESTEDIN"));

        StringBuilder newInterestedInSb = new StringBuilder();
        boolean isFirst = true;
        for (InterestedIn interestedIn : newInterestedIn) {
            if (!isFirst) {
                newInterestedInSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            newInterestedInSb.append(interestedIn.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(newInterestedInSb.toString());
        newInterestedInTargetingDescriptionBo.setChildren(children);

        return newInterestedInTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildBroadCategoriesTargetingDescriptionBo(List<BroadCategory> broadCategories) {
        if (null == broadCategories || CollectionUtils.isEmpty(broadCategories)) {
            return null;
        }

        TargetingDescriptionBo broadCategoriesTargetingDescriptionBo = new TargetingDescriptionBo();
        broadCategoriesTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_BROADCATEGORY"));

        StringBuilder broadCategoriesSb = new StringBuilder();
        boolean isFirst = true;
        for (BroadCategory broadCategory : broadCategories) {
            if (!isFirst) {
                broadCategoriesSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            isFirst = false;
            broadCategoriesSb.append(broadCategory.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(broadCategoriesSb.toString());
        broadCategoriesTargetingDescriptionBo.setChildren(children);

        return broadCategoriesTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildRelationshipTargetingDescriptionBo(List<Integer> relationshipStatus) {
        if (null == relationshipStatus || org.springframework.util.CollectionUtils.isEmpty(relationshipStatus)) {
            return null;
        }

        TargetingDescriptionBo relationshipTargetingDescriptionBo = new TargetingDescriptionBo();
        relationshipTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_MARITAL"));

        StringBuilder relationshipSb = new StringBuilder();
        boolean isFirst = true;
        for (Integer relationship : relationshipStatus) {
            if (!isFirst) {
                relationshipSb.append(CommonConstants.SYMBOL_COMMA);
            }
            isFirst = false;
            relationshipSb.append(RelationShipStatusType.getRelationShipStatus(relationship).getLocalRelationShipStatus());
        }

        List<String> children = new ArrayList<>();
        children.add(relationshipSb.toString());
        relationshipTargetingDescriptionBo.setChildren(children);

        return relationshipTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildConnectionTargetingDescriptionBo(LocalConnection localConnection) {
        if (null == localConnection || org.springframework.util.CollectionUtils.isEmpty(localConnection.getConnections())) {
            return null;
        }

        FacebookConnection facebookConnection = localConnection.getConnections().get(0);
        StringBuilder interestsSb = new StringBuilder();
        Connections connections = Connections.getConnections(localConnection.getType());
        if (Connections.Connections == connections) {
            //Only people connected to Fantasy Of Elements
            interestsSb.append("Only people connected to " + facebookConnection.getName());
        } else if (Connections.Excluded_connections == connections) {
            //Only people not connected to Fantasy Of Elements
            interestsSb.append(ResponseUtils.getMsgByKey("WALLE_EXCLUDE_WHO_HAS_INSTALL"));
            interestsSb.append(facebookConnection.getName());
            interestsSb.append(ResponseUtils.getMsgByKey("WALLE_EXCLUDE_WHO_HAS_INSTALL_USER"));
        } else {
            return null;
        }

        TargetingDescriptionBo connectionTargetingDescriptionBo = new TargetingDescriptionBo();
        connectionTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_CONNECTION"));

        List<String> children = new ArrayList<>();
        children.add(interestsSb.toString());
        connectionTargetingDescriptionBo.setChildren(children);

        return connectionTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildInterestedInTargetingDescriptionBo(List<Integer> interestedIns) {
        if (null == interestedIns || org.springframework.util.CollectionUtils.isEmpty(interestedIns)) {
            return null;
        }

        TargetingDescriptionBo interestedInTargetingDescriptionBo = new TargetingDescriptionBo();
        interestedInTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_INTERESTEDIN"));

        StringBuilder interestedInsSb = new StringBuilder();
        boolean isFirst = true;
        for (Integer interestedIn : interestedIns) {
            if (!isFirst) {
                interestedInsSb.append(CommonConstants.SYMBOL_COMMA);
            }
            isFirst = false;
            interestedInsSb.append(InterestedInType.getInterestedIn(interestedIn).getInterestedIn());
        }

        List<String> children = new ArrayList<>();
        children.add(interestedInsSb.toString());
        interestedInTargetingDescriptionBo.setChildren(children);

        return interestedInTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildWirelessConnectionTargetingDescriptionBo(List<Integer> wirelessConnections) {
        if (null == wirelessConnections || org.springframework.util.CollectionUtils.isEmpty(wirelessConnections)) {
            return null;
        }

        TargetingDescriptionBo wirelessConnectionTargetingDescriptionBo = new TargetingDescriptionBo();
        wirelessConnectionTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_WIRELESS_CONNECTION"));

        StringBuilder wirelessConnectionsSb = new StringBuilder();
        boolean isFirst = true;
        for (Integer wirelessConnection : wirelessConnections) {
            if (!isFirst) {
                wirelessConnectionsSb.append(CommonConstants.SYMBOL_COMMA);
            }
            isFirst = false;

            //处理无线
            WirelessCarrier wirelessCarrier = WirelessCarrier.getWirelessCarrier(wirelessConnection);
            if(null == wirelessCarrier || wirelessCarrier != WirelessCarrier.Wifi){
                continue;
            }

            wirelessConnectionsSb.append(WirelessCarrier.getWirelessCarrier(wirelessConnection).getShowWirelessCarrier());
        }

        List<String> children = new ArrayList<>();
        children.add(wirelessConnectionsSb.toString());
        wirelessConnectionTargetingDescriptionBo.setChildren(children);

        return wirelessConnectionTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildUserOSTargetingDescriptionBo(Platform platform) {
        if (null == platform || null == platform.getType() || org.springframework.util.CollectionUtils.isEmpty(platform.getUserOS())) {
            return null;
        }

        TargetingDescriptionBo userOSsTargetingDescriptionBo = new TargetingDescriptionBo();
        userOSsTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_USER_OS"));

        Integer type = platform.getType();
        String osPrefix;
        String osPostfix = ResponseUtils.getMsgByKey("WALLE_OSPOSTFIX");
        if (UserOs.iOS.getCode() == type || type ==3) {
            //IOS
            osPrefix = "iOS" + ResponseUtils.getMsgByKey("WALLE_VERSION");

        } else {
            //Android
            osPrefix = "android" + ResponseUtils.getMsgByKey("WALLE_VERSION");
        }

        List<String> userOSs = platform.getUserOS();
        StringBuilder userOSsSb = new StringBuilder();
        boolean isFirst = true;
        BuildCacheUtils.userOSAppend(osPrefix, osPostfix, userOSs, userOSsSb, isFirst);
        List<String> children = new ArrayList<>();
        children.add(userOSsSb.toString());
        userOSsTargetingDescriptionBo.setChildren(children);
        return userOSsTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildUserDeviceTargetingDescriptionBo(Platform platform) {
        if (null == platform || org.springframework.util.CollectionUtils.isEmpty(platform.getUserDevice())) {
            return null;
        }

        TargetingDescriptionBo userDevicesTargetingDescriptionBo = new TargetingDescriptionBo();
        userDevicesTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_USER_DEVICE"));

        List<String> userDevices = platform.getUserDevice();
        StringBuilder userDevicesSb = new StringBuilder();
        boolean isFirst = true;
        BuildCacheUtils.userDeviceAppend(userDevices, userDevicesSb, isFirst);
        List<String> children = new ArrayList<>();
        children.add(userDevicesSb.toString());
        userDevicesTargetingDescriptionBo.setChildren(children);

        return userDevicesTargetingDescriptionBo;
    }


    private TargetingDescriptionBo buildBehaviorsTargetingDescriptionBo(List<Behavior> behaviorList) {
        if (ListUtil.isEmpty(behaviorList)) {
            return null;
        }
        TargetingDescriptionBo behaviorsTargetingDescriptionBo = new TargetingDescriptionBo();
        behaviorsTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_BEHAVIOR"));

        StringBuffer behaviorsSb = new StringBuffer();
        boolean isFirst = true;
        for (Behavior b : behaviorList) {
            if (!isFirst) {
                behaviorsSb.append(CommonConstants.SYMBOL_COMMA);
            }
            isFirst = false;
            behaviorsSb.append(b.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(behaviorsSb.toString());
        behaviorsTargetingDescriptionBo.setChildren(children);
        return behaviorsTargetingDescriptionBo;
    }


    private TargetingDescriptionBo buildGenderTargetingDescriptionBo(LocalGender localGender) {
        if (null == localGender || org.springframework.util.CollectionUtils.isEmpty(localGender.getGenders())) {
            return null;
        }

        TargetingDescriptionBo genderTargetingDescriptionBo = new TargetingDescriptionBo();
        genderTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_GENDER"));

        StringBuilder genderSb = new StringBuilder();
        boolean isFirst = true;
        List<Integer> genders = localGender.getGenders();
        List<Integer> tmpArray = new ArrayList<>();

        for (Integer gender : genders) {
            if(gender != null && gender.intValue() != 0){
                tmpArray.add(gender);
            }
        }

        for (Integer gender : tmpArray) {
            if (!isFirst) {
                genderSb.append(CommonConstants.SYMBOL_COMMA);
            }
            isFirst = false;

            Gender gender1 = Gender.getGender(gender);
            System.out.println("gender1 >>>>>>>>>>" +gender1);
            genderSb.append(gender1.getGender());
        }

        List<String> children = new ArrayList<>();
        children.add(genderSb.toString());
        genderTargetingDescriptionBo.setChildren(children);

        return genderTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildAgeTargetingDescriptionBo(Age age) {
        if (null == age) {
            return null;
        }

        TargetingDescriptionBo ageTargetingDescriptionBo = new TargetingDescriptionBo();
        ageTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_AGE"));

        Integer ageMin = age.getAgeMin();
        Integer ageMax = age.getAgeMax();

        StringBuilder ageSb = new StringBuilder();
        ageSb.append(ageMin);


        //如果年龄上限等于年龄下限，则显示年龄下限即可
        BuildCacheUtils.ageAppend( ageMin,  ageMax,  ageSb);
        List<String> children = new ArrayList<>();
        children.add(ageSb.toString());
        ageTargetingDescriptionBo.setChildren(children);

        return ageTargetingDescriptionBo;
    }

    private TargetingDescriptionBo buildCountryTargetingDescriptionBo(LocalLocation localLocation) {
        if (null == localLocation || (CollectionUtils.isEmpty(localLocation.getCities())
                && org.springframework.util.CollectionUtils.isEmpty(localLocation.getCountries()))) {
            return null;
        }

        //根据定位条件 获取头描述
        String content = getContentByLocationType(localLocation);

        TargetingDescriptionBo countryTargetingDescriptionBo = new TargetingDescriptionBo();
        countryTargetingDescriptionBo.setContent(content);

        List<String> children = buildLocationDescription(localLocation);
        countryTargetingDescriptionBo.setChildren(children);

        return countryTargetingDescriptionBo;
    }

    private List<String> buildLocationDescription(LocalLocation localLocation) {
        List<Country> countries = localLocation.getCountries();
        List<City> cities = localLocation.getCities();
        StringBuilder countriesSb = new StringBuilder();
        boolean isFirst = true;
        if (!CollectionUtils.isEmpty(countries)) {
            for (Country country : countries) {
                if (!isFirst) {
                    countriesSb.append(CommonConstants.SYMBOL_COMMA);
                }
                isFirst = false;
                countriesSb.append(country.getName());
            }
        }
        if (!CollectionUtils.isEmpty(cities)) {
            for (City city : cities) {
                if (!isFirst) {
                    countriesSb.append(CommonConstants.SYMBOL_COMMA);
                }
                isFirst = false;
                countriesSb.append(city.getName());
            }
        }
        List<String> children = new ArrayList<>();
        children.add(countriesSb.toString());
        return children;
    }

    private String getContentByLocationType(LocalLocation localLocation) {
        String content;
        Integer locationType = localLocation.getLocationType();
        if (null == locationType) {
            content = ResponseUtils.getMsgByKey("WALLE_LOCATION");
        } else {
            LocationType locationTypeE = LocationType.getLocationType(locationType);

            switch (locationTypeE) {
                case All:
                    content = ResponseUtils.getMsgByKey("WALLE_LOCATION");
                    break;
                case Recent:
                    content = ResponseUtils.getMsgByKey("WALLE_LOCATION_RECENT");
                    break;
                case Travel_in:
                    content = ResponseUtils.getMsgByKey("WALLE_LOCATION_TRAVEL");
                    break;
                case Home:
                    content = ResponseUtils.getMsgByKey("WALLE_LOCATION_HOME");
                    break;
                default:
                    content = ResponseUtils.getMsgByKey("WALLE_LOCATION");
                    break;
            }
        }

        return content;
    }

    private TargetingDescriptionBo buildInterestTargetingDescriptionBo(LocalInterest localInterest) {
        if (null == localInterest || org.springframework.util.CollectionUtils.isEmpty(localInterest.getInterests())) {
            return null;
        }

        TargetingDescriptionBo interestTargetingDescriptionBo = new TargetingDescriptionBo();
        interestTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_INTEREST"));

        StringBuilder interestsSb = new StringBuilder();
        boolean isFirst = true;
        List<Interest> interests = localInterest.getInterests();
        for (Interest interest : interests) {
            if (!isFirst) {
                interestsSb.append(CommonConstants.SYMBOL_COMMA);
            }
            isFirst = false;
            interestsSb.append(interest.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(interestsSb.toString());
        interestTargetingDescriptionBo.setChildren(children);

        return interestTargetingDescriptionBo;

    }

    private TargetingDescriptionBo buildLanguagesTargetingDescriptionBo(List<Language> languages) {
        if (null == languages || org.springframework.util.CollectionUtils.isEmpty(languages)) {
            return null;
        }

        TargetingDescriptionBo languagesTargetingDescriptionBo = new TargetingDescriptionBo();
        languagesTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_LANGUAGE"));

        StringBuilder languagesSb = new StringBuilder();
        boolean isFirst = true;
        for (Language language : languages) {
            if (!isFirst) {
                languagesSb.append(CommonConstants.SYMBOL_COMMA);
            }
            isFirst = false;
            languagesSb.append(language.getName());
        }

        List<String> children = new ArrayList<>();
        children.add(languagesSb.toString());
        languagesTargetingDescriptionBo.setChildren(children);

        return languagesTargetingDescriptionBo;
    }

    private List<TargetingDescriptionBo> buildCustomAudienceTargetingDescriptionBo(LocalCustomAudience localCustomAudience) {
        if (null == localCustomAudience || null == localCustomAudience.getFbAccountId()
                || (CollectionUtils.isEmpty(localCustomAudience.getCustomAudiences())
                && CollectionUtils.isEmpty(localCustomAudience.getExcludedCustomAudiences()))) {
            return null;
        }

        List<TargetingDescriptionBo> targetingDescriptionBoes = new ArrayList<>();

        //账号
        TargetingDescriptionBo accountTargetingDescriptionBo = new TargetingDescriptionBo();
        accountTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_ACCOUNT"));
        List<String> accountChildren = new ArrayList<>();
        accountChildren.add(localCustomAudience.getFbAccountName());
        accountTargetingDescriptionBo.setChildren(accountChildren);
        targetingDescriptionBoes.add(accountTargetingDescriptionBo);

        //包含
        if (!CollectionUtils.isEmpty(localCustomAudience.getCustomAudiences())) {
            List<CustomAudience> customAudiences = localCustomAudience.getCustomAudiences();
            TargetingDescriptionBo includeTargetingDescriptionBo = new TargetingDescriptionBo();
            includeTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_INCLUDE"));
            List<String> includeTargetingChildren = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            boolean isFirst = true;
            BuildCacheUtils.customAudienceAppend(customAudiences, sb, isFirst);
            includeTargetingChildren.add(sb.toString());
            includeTargetingDescriptionBo.setChildren(includeTargetingChildren);
            targetingDescriptionBoes.add(includeTargetingDescriptionBo);
        }

        //不包含
        if (!CollectionUtils.isEmpty(localCustomAudience.getExcludedCustomAudiences())) {
            List<CustomAudience> excludedCustomAudience = localCustomAudience.getExcludedCustomAudiences();
            TargetingDescriptionBo excludeTargetingDescriptionBo = new TargetingDescriptionBo();
            excludeTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_EXCLUDE"));
            List<String> excludeTargetingChildren = new ArrayList<>();
            StringBuilder sb = new StringBuilder();
            boolean isFirst = true;
            BuildCacheUtils.customAudienceAppend(excludedCustomAudience, sb, isFirst);
            excludeTargetingChildren.add(sb.toString());
            excludeTargetingDescriptionBo.setChildren(excludeTargetingChildren);
            targetingDescriptionBoes.add(excludeTargetingDescriptionBo);
        }

        return targetingDescriptionBoes;
    }


    private TargetingDescriptionBo buildPageTypeTargetingDescriptionBo(LocalPageType localPageType) {

        if (null == localPageType || org.springframework.util.CollectionUtils.isEmpty(localPageType.getPageTypes())) {
            return null;
        }

        TargetingDescriptionBo genderTargetingDescriptionBo = new TargetingDescriptionBo();
        genderTargetingDescriptionBo.setContent(ResponseUtils.getMsgByKey("WALLE_PAGE_TYPE"));

        boolean isFirst = true;
        StringBuilder pageTypeSb = new StringBuilder();
        List<Integer> pageTypes = localPageType.getPageTypes();
        //这个方法里面未作国际化 todo evan
//        BuildCacheUtils.pageAppend(pageTypes, isFirst, pageTypeSb);
        for (Integer pageType : pageTypes) {
            if (!isFirst) {
                pageTypeSb.append(CommonConstants.SYMBOL_COMMA_CHINA);
            }
            pageTypeSb.append(ResponseUtils.getMsgByKey(PageType.getPageType(pageType).getShowPageTypeName()));

            isFirst = false;
        }

        List<String> children = new ArrayList<>();
        children.add(pageTypeSb.toString());
        genderTargetingDescriptionBo.setChildren(children);

        return genderTargetingDescriptionBo;
    }

    private void targetUserAudienceByAccounts(String batchCacheId, String userAudienceCacheId,
                                              List<TargetingSpecGroupBo> groups, EntrustAccountParam accountParam) {
        TargetingSpecParam targetingSpecReachEstimateParam;
        for (TargetingSpecGroupBo tsg : groups) {
            //请求潜在用户参数
            targetingSpecReachEstimateParam = new TargetingSpecParam();
            targetingSpecReachEstimateParam.setTargetingSpec(tsg.getTargetingSpecs());
            targetingSpecReachEstimateParam.setCallBack(true);
            targetingSpecReachEstimateParam.setFbAccountId(Long.parseLong(accountParam.getAccountId()));
            targetingSpecReachEstimateParam.setAccessToken(accountParam.getAccessToken());
            targetingSpecReachEstimateParam.setApiCallbackTargetType(ApiCallBackTarget.AdPublish.TargetingSpec.getTargetType());
            targetingSpecReachEstimateParam.setApiPriorityCode(APIPriority.UserAudienceReach.getCode());
            targetingSpecReachEstimateParam.setOptimizeFor(OptimizationGoal.LINK_CLICKS.getCode()); //todo verify to others
            Map<String, String> equipment = new HashMap<>();
            equipment.put("publishCacheId", batchCacheId);
            equipment.put("userAudienceCacheId", userAudienceCacheId);
            equipment.put("groupId", tsg.getGroupId());
            targetingSpecReachEstimateParam.setEquipment(equipment);

            //请求潜在用户参数
            targetingHelper.targetingSpecReachEstimate(targetingSpecReachEstimateParam);
            LOG.info("UserAudienceServiceImpl->targetUserAudienceByAccounts->请求用户定位人数，publishCacheId："
                    + batchCacheId + "，userAudienceCacheId：" + userAudienceCacheId + "，groupId："
                    + tsg.getGroupId() + "，accountId：" + accountParam.getAccountId());
        }
    }
    /**
     * @param targetingSpecGroups targetingSpecGroups
     * @return Set<TargetingSpecGroup>
     * @description 获取自定义受众描述组
     */
    private List<TargetingSpecGroupBo> getTargetingSpecGroups(String targetingSpecGroups) throws BusinessException {
        List<List<TargetingSpecBo>> list = getList(targetingSpecGroups);
        List<TargetingSpecBo> arr = list.get(0);

        List<TargetingSpecGroupBo> groups = new ArrayList<>();

        getSepcGroups(list, arr, new ArrayList<TargetingSpecBo>(), groups);

        return groups;
    }

    /**
     * 解析json为需要的集合数据
     *
     * @param audienceJson audienceJson
     * @return List<TargetingSpecBo[]>
     */
    private List<List<TargetingSpecBo>> getList(String audienceJson) {
        // 将所有spec的可能性存入到map中
        List<List<TargetingSpecBo>> list = new ArrayList<>();
        TargetingSpecBo targetingSpecs;
        List<TargetingSpecBo> targetingSpecsList;
        TargetingType targetingType;
        Map<String, List<String>> result =
                JSON.parseObject(audienceJson, new TypeReference<Map<String, List<String>>>() {
                });
        List<String> specStrs;
        for (Map.Entry<String, List<String>> specs : result.entrySet()) {
            targetingSpecsList = new ArrayList<>();
            targetingType = TargetingType.valueOf(specs.getKey());
            specStrs = specs.getValue();
            Long index = 0L;
            if(ListUtil.isEmpty(specStrs)){
                System.out.println("参数异常>>>"+targetingType);
            }
            for (String specStr : specStrs) {
                targetingSpecs = new TargetingSpecBo();
                targetingSpecs.setIndex(index);
                targetingSpecs.setSpec(specStr);
                targetingSpecs.setType(targetingType);
                targetingSpecsList.add(targetingSpecs);
                index++;
            }
            list.add(targetingSpecsList);
        }
        return list;
    }

    /**
     * 组合排列所有表单specs
     *
     * @param list   元素集合
     * @param arr    集合第一个元素
     * @param specs  specs
     * @param groups groups
     */
    private void getSepcGroups(List<List<TargetingSpecBo>> list,
                               List<TargetingSpecBo> arr, List<TargetingSpecBo> specs,
                               List<TargetingSpecGroupBo> groups) {
        for (int i = 0; i < list.size(); i++) {
            // 取得当前的数组
            if (i == list.indexOf(arr)) {
                // 迭代数组
                for (TargetingSpecBo st : arr) {
                    List<TargetingSpecBo> sList = new ArrayList<>(specs);
                    sList.add(st);
                    if (i < list.size() - 1) {
                        getSepcGroups(list, list.get(i + 1), sList, groups);
                    } else if (i == list.size() - 1) {
                        TargetingSpecGroupBo group = new TargetingSpecGroupBo();
                        for (TargetingSpecBo t : sList) {
                            try {
                                group.addTargetingSpecBo(t.clone());
                            } catch (CloneNotSupportedException e) {
                                e.printStackTrace();
                            }
                        }
                        groups.add(group);
                    }
                }
            }
        }
    }


	@Override
	public String previewUserAudience(String targeting_spec, FbUser fbUser, Long accountId) throws BusinessException {
		TargetingSpecParam targetingSpecReachEstimateParam = new TargetingSpecParam();
		targetingSpecReachEstimateParam.setTargetingSpec(targeting_spec);
		targetingSpecReachEstimateParam.setCallBack(true);
		targetingSpecReachEstimateParam.setFbAccountId(accountId);
		targetingSpecReachEstimateParam.setAccessToken(fbUser.getAccessToken());
		targetingSpecReachEstimateParam
				.setApiCallbackTargetType(ApiCallBackTarget.AdPublish.SimpleTargetingSpec.getTargetType());
		targetingSpecReachEstimateParam.setApiPriorityCode(APIPriority.UserAudienceReach.getCode());
		targetingSpecReachEstimateParam.setOptimizeFor(OptimizationGoal.LINK_CLICKS.getCode()); // todo
																								// verify
																								// to
		Map<String, String> equipment = new HashMap<>();
		String cacheId = UUID.randomUUID().toString();
		equipment.put("publishCacheId", cacheId);
        equipment.put("targetingSpec",targeting_spec);
		String userAudienceCacheId = UUID.randomUUID().toString();
		equipment.put("userAudienceCacheId", userAudienceCacheId);
		equipment.put("groupId", "1");
		targetingSpecReachEstimateParam.setEquipment(equipment);

		// 请求潜在用户参数
		targetingHelper.targetingSpecReachEstimate(targetingSpecReachEstimateParam);
		LOG.info("UserAudienceServiceImpl->targetUserAudienceByAccounts->请求用户定位人数，publishCacheId：" + cacheId
				+ "，userAudienceCacheId：" + userAudienceCacheId + "，groupId：" + 1 + "，accountId："
				+ accountId);
		return userAudienceCacheId;
	}


	@Override
	public PreviewUserAudienceResult searchPreviewSimpleUserAudienceResult(String cacheId) throws BusinessException {
		PreviewUserAudienceResult previewUserAudienceResult = new PreviewUserAudienceResult();
        previewUserAudienceResult.setGroupCount(1);
        TargetingSpecGroupBo tar = (TargetingSpecGroupBo)redisClient.get(cacheId);
        if(tar==null){
            previewUserAudienceResult.setIsComplete(false);
        }else{
        	List<TargetingSpecGroupBo> targetingSpecGroupBoes = new ArrayList<>();
        	targetingSpecGroupBoes.add(tar);
        	previewUserAudienceResult.setPreviewUserAudienceResults(targetingSpecGroupBoes);
            previewUserAudienceResult.setIsComplete(true);
        }
		return previewUserAudienceResult;
	}


    @Override
    public List<EntrustAccount> findAccountsByWeFeedId(Long weFeedId) {
        FeedWe feedWe = feedRdbService.findFeedWeById(weFeedId);
        if (null == feedWe){
            return null;
        }
        ProductManage productManage = productManageRdbService.findById(feedWe.getProductId());
        if (null == productManage){
            return null;
        }
        PlatForm platForm =  PlatForm.getPlatForm(productManage.getProdPlatform());
        //获取当前Feed对应产品支持的账号
        return adPublishConditionService.findAllowedAccounts(feedWe.getUserId(), productManage.getProdId(), platForm.getKey().longValue());
    }

    @Override
    public  Map<String, Object> validateProductSetList(String ticket, Long weFeedId) {
        Map<String, Object> results = new HashMap<>();

        FeedWe cfeed = feedService.getFeed(weFeedId);
        if (null == cfeed){
            return results;
        }
        
        //通过用户Id查询该用户下的账号信息
        List<EntrustAccount> entrustAccounts = ecService.findAccountsByProdIdAndUserId(cfeed.getProductId(), ticket);
        if (CollectionUtils.isEmpty(entrustAccounts)){
            return results;
        }
        //暂定取第一个有权限的账号作为，检验用户定位的账号
        results.put("account", entrustAccounts.get(0));

        //查询Feed下已经完成的产品系列
        List<Long> feedIds = new ArrayList<>();
        Map<Long, FeedWe> feedMap = new HashMap<>();
        feedIds.add(weFeedId);
        feedMap.put(weFeedId, cfeed);

        String fj = JSON.toJSONString(feedIds);
        JSONArray productSets = productsetService.getProductSetsByFeed(JSONArray.parseArray(fj), "finished");
        if (null == productSets || productSets.isEmpty()){
            return results;
        }

       List<ProductExt> productSetExts = new ArrayList<>();
        Long feedId;
        FeedWe feed;
        ProductExt productExt;
        JSONArray fbIds;
        for (Object productSet : productSets){
            JSONObject temp = (JSONObject)productSet;
            fbIds = temp.getJSONArray("fb_ids");
            if (null == fbIds || fbIds.isEmpty()){
                continue;
            }

            feedId = temp.getLong("feed_id");
            feed = feedMap.get(feedId);

            productExt = new ProductExt();
            productExt.setProductId(feed.getProductId());
            productExt.setProductName(feed.getProductName());
            productExt.setFeedId(feedId);
            productExt.setCatalogId(((JSONObject) fbIds.get(0)).getLong("catalog_id"));
            productExt.setFbProductSetId(((JSONObject) fbIds.get(0)).getLong("fb_productset_id"));
            productExt.setProductSetId(temp.getString("id"));
            productExt.setProductSetName(temp.getString("name"));

            productSetExts.add(productExt);
        }

        results.put("productSets", productSetExts);
        return results;
    }
}